﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Win32;
using System.IO;
using System.Data;
using System.Diagnostics;

namespace ToolsCentura
{
    public class ToolsCentura
    {
        public event Action<string> Notificar;
        
        public ToolsCentura()
        {
            ProjectFiles = new DataTable();
        }
        private string _ActiveXLibraries;
        public string ActiveXLibraries
        {
            get
            {
                RegistryKey rkActiveX = Registry.CurrentUser.OpenSubKey(@"Software\Centura\SQLWindows 2.1\ActiveX", true);
                _ActiveXLibraries = rkActiveX.GetValue("DefaultDir").ToString();
                return _ActiveXLibraries;
            }
            set
            {
                _ActiveXLibraries = value;
                RegistryKey rkActiveX = Registry.CurrentUser.OpenSubKey(@"Software\Centura\SQLWindows 2.1\ActiveX", true);
                rkActiveX.SetValue("DefaultDir", _ActiveXLibraries, RegistryValueKind.String);
            }
        }

        private string _GlobalPath;
        public string GlobalPath
        {
            get
            {
                RegistryKey rkGlobal = Registry.CurrentUser.OpenSubKey(@"Software\Centura\SQLWindows 2.1\Settings", true);
                _GlobalPath = rkGlobal.GetValue("IncludePath").ToString();
                return _GlobalPath;
            }
            set
            {
                _GlobalPath = value;
                RegistryKey rkGlobal = Registry.CurrentUser.OpenSubKey(@"Software\Centura\SQLWindows 2.1\Settings", true);
                rkGlobal.SetValue("IncludePath", _GlobalPath, RegistryValueKind.String);
            }
        }

        public DataTable ProjectFiles { get; set; }
        public void LoadProjectFiles(string path, bool version, string newVersion)
        {
            if (string.IsNullOrEmpty(path))
                return;

            string[] filesApp = Directory.GetFiles(path, "*.app", SearchOption.AllDirectories);
            string[] filesApt = Directory.GetFiles(path, "*.apt", SearchOption.AllDirectories);
            List<string[]> listProjectFiles = new List<string[]>();
            listProjectFiles.Add(filesApp);
            listProjectFiles.Add(filesApt);

            ProjectFiles.Clear();
            ProjectFiles.Columns.Clear();

            ProjectFiles.Columns.Add("Path", typeof(string)).ReadOnly = true;
            ProjectFiles.Columns.Add("File", typeof(string)).ReadOnly = true;
            ProjectFiles.Columns.Add("Old Version", typeof(string));
            ProjectFiles.Columns.Add("New Version", typeof(string));
            ProjectFiles.Columns.Add("Update", typeof(bool));
            ProjectFiles.Columns.Add("Compile", typeof(bool));
            ProjectFiles.Columns.Add("Status", typeof(string));
            ProjectFiles.Columns.Add("File Error", typeof(string));

            string fileVersion;
            FileInfo fi;
            foreach (string[] projectFiles in listProjectFiles)
            {
                foreach (string projectFile in projectFiles)
                {
                    fileVersion = "";
                    fi = new FileInfo(projectFile);
                    if (!fi.IsReadOnly)
                    {
                        if (version)
                        {
                            fileVersion = GetSisVersion(projectFile);
                        }
                        ProjectFiles.Rows.Add(fi.DirectoryName,
                                              fi.Name,
                                              fileVersion,
                                              newVersion,
                                              true,
                                              true,
                                              "",
                                              "");
                    }
                }
            }
        }

        public string GetSisVersion(string file)
        {
            string version = "NÃO POSSUI";
            string arqText;
            string txtVersion;
            int posIni;
            int posFim;

            arqText = File.ReadAllText(file, System.Text.Encoding.Default);
            posIni = arqText.IndexOf("-  String: SIS_VERSAO = '");
            if (posIni > -1)
            {
                posFim = arqText.IndexOf("'", posIni + 25);
                txtVersion = arqText.Substring(posIni, posFim - posIni);
                version = txtVersion.Remove(0, 25);
            }
            return version;
        }

        public void SetSisVersion(string file, string version)
        {
            string arqText;
            string txtVersion;
            int posIni;
            int posFim;

            arqText = File.ReadAllText(file, System.Text.Encoding.Default);
            posIni = arqText.IndexOf("-  String: SIS_VERSAO = '");

            if (posIni > -1)
            {
                posFim = arqText.IndexOf("'", posIni + 25);
                txtVersion = arqText.Substring(posIni, posFim - posIni);

                File.WriteAllText(file,
                                  arqText.Replace(txtVersion, "-  String: SIS_VERSAO = '" + version),
                                  System.Text.Encoding.Default);
            }
        }

        public void SetAllNewVersion(string newVersion)
        {
            foreach (DataRow dr in ProjectFiles.Rows)
            {
                dr["New Version"] = newVersion;
            }
        }
        
        public void SetAllUpdate(bool update)
        {
            foreach (DataRow dr in ProjectFiles.Rows)
            {
                dr["Update"] = update;
            }
        }
        
        public void SetAllCompile(bool compile)
        {
            foreach (DataRow dr in ProjectFiles.Rows)
            {
                dr["Compile"] = compile;
            }
        }

        private Process process;
        private Dictionary<int, DataRow> dctFileProcess;
        private DateTime dtStartBuild;
        private void StartBuildFilesCentura(string file, DataRow dr)
        {
            process = new Process();
            process.StartInfo.WorkingDirectory = @"C:\Program Files\Centura";
            process.StartInfo.FileName = @"C:\Program Files\Centura\cbi21.exe";
            process.StartInfo.Arguments = " -b " + file;
            process.StartInfo.UseShellExecute = false;
            process.OutputDataReceived += new DataReceivedEventHandler(process_OutputDataReceived);
            process.StartInfo.RedirectStandardOutput = true;
            process.Start();
            process.BeginOutputReadLine();
            dctFileProcess.Add(process.Id, dr);
        }
        private void process_OutputDataReceived(object sender, DataReceivedEventArgs e)
        {
            string fileErr;
            fileErr = ((Process)sender).StartInfo.Arguments.ToLower().Replace(".app", ".err");
            fileErr = fileErr.Replace(".apt", ".err");
            fileErr = fileErr.Replace("-b", "");
            fileErr = fileErr.Trim();

            string fileExe;
            fileExe = fileErr.Replace(".err", ".exe");

            int idProcess = ((Process)sender).Id;
            if (!File.Exists(fileErr))
            {
                if (File.Exists(fileExe))
                {
                    if (new FileInfo(fileExe).LastWriteTime < dtStartBuild)
                    {
                        (dctFileProcess[idProcess])["Status"] = "ERRO Centura";
                        (dctFileProcess[idProcess])["Compile"] = true;
                        (dctFileProcess[idProcess])["File Error"] = "";
                    }
                    else
                    {
                        (dctFileProcess[idProcess])["Status"] = "Finalizado";
                        (dctFileProcess[idProcess])["Compile"] = false;
                        (dctFileProcess[idProcess])["File Error"] = "";
                    }
                }
                else
                {
                    (dctFileProcess[idProcess])["Status"] = "ERRO Centura";
                    (dctFileProcess[idProcess])["Compile"] = true;
                    (dctFileProcess[idProcess])["File Error"] = "";
                }
            }
            else
            {
                (dctFileProcess[idProcess])["Status"] = "ERRO";
                (dctFileProcess[idProcess])["File Error"] = fileErr;
            }
        }
        public void BuildFilesCentura()
        {
            string file;
            bool update;
            bool compile;
            string version;
            dtStartBuild = DateTime.Now;
            dctFileProcess = new System.Collections.Generic.Dictionary<int, DataRow>();

            foreach (DataRow dr in ProjectFiles.Rows)
            {
                update = Convert.ToBoolean(dr["Update"]);
                compile = Convert.ToBoolean(dr["Compile"]);
                if (update || compile)
                {
                    file = dr["Path"].ToString() + @"\" + dr["File"].ToString();
                    version = dr["New Version"].ToString();
                    if (update)
                    {
                        dr["Status"] = "Processando";
                        dr["Old Version"] = version;

                        if (Notificar != null)
                            Notificar("Processando");

                        SetSisVersion(file, version);
                        dr["Update"] = false;
                        dr["Status"] = "";
                    }
                    if (compile)
                    {
                        dr["Status"] = "Compilando";
                        File.Delete(file.ToLower().Replace(".app", ".err").Replace(".apt", ".err").Trim());
                        StartBuildFilesCentura(file, dr);
                    }
                }
            }
        }

        public string BuildFileCentura(string file)
        {
            File.Delete(file.ToLower().Replace(".app", ".err").Replace(".apt", ".err").Trim());
            string error;
            DateTime dtStartBuildLocal = DateTime.Now;
            Process processLocal = new Process();
            processLocal.StartInfo.WorkingDirectory = @"C:\Program Files\Centura";
            processLocal.StartInfo.FileName = @"C:\Program Files\Centura\cbi21.exe";
            processLocal.StartInfo.Arguments = " -b " + file;
            processLocal.Start();
            processLocal.WaitForExit();
            error = GetErrorBuildFileCentura(file, dtStartBuildLocal);
            return error;
        }
        private string GetErrorBuildFileCentura(string file, DateTime startBuildDate)
        {
            string fileErr;
            fileErr = file.ToLower().Replace(".app", ".err");
            fileErr = fileErr.Replace(".apt", ".err");
            fileErr = fileErr.Replace("-b", "");
            fileErr = fileErr.Trim();

            string fileExe;
            fileExe = fileErr.Replace(".err", ".exe");

            string error = "";
            if (!File.Exists(fileErr))
            {
                if (File.Exists(fileExe))
                {
                    if (new FileInfo(fileExe).LastWriteTime < startBuildDate)
                    {
                        error = "ERRO Centura";
                    }
                    else
                    {
                        error = "Finalizado";
                    }
                }
                else
                {
                    error = "ERRO Centura";
                }
            }
            else
            {
                error = "ERRO";
            }
            return error;
        }
    }
}
